package cn.com.hhrcw.web;

import cn.com.hhrcw.base.BaseParams;
import cn.com.hhrcw.constant.CommonConstant;
import cn.com.hhrcw.entity.*;
import cn.com.hhrcw.es.entity.JobPositionDocument;
import cn.com.hhrcw.es.service.IElasticsearchService;
import cn.com.hhrcw.personal.wxlogin.util.Constant;
import cn.com.hhrcw.service.*;
import cn.com.hhrcw.utils.SubjectUtils;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.apache.shiro.SecurityUtils;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.common.system.vo.DictModel;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.DigestUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotBlank;
import java.io.IOException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.TimeUnit;


/**
 * 与顶端新闻对接，token登录
 *
 * @author
 * @since 2023年04月19日16:54:16
 */
@RestController
@RequestMapping("/personal/top/job")
@Slf4j
@Validated
public class TopJobClientController extends JeecgController<SysUser, ISysUserService>{
    @Autowired
    private IElasticsearchService elasticsearchService;
    @Autowired
    private ISysUserService sysUserService;
    @Autowired
    private IOpJobService jobService;
    @Autowired
    private IOpCollectionService opCollectionService;
    @Autowired
    protected RedisTemplate redisTemplate;
    @Autowired
    NewResumeService newResumeService;
    @Value(value = "${jeecg.uploadType}")
    private String uploadType;
    @Autowired
    private ISysBaseAPI sysBaseApi;
    @Autowired
    protected TopJobClientService topJobClientService;
    @Autowired
    ICvResumeService resumeService;
    @Value("${spring.profiles.active}")
    private String profiles;
    public static final int EXPIR_DAY = 30;
    public static final String app_id = "230424168230583201";
    public static final String appSecret = "3d78f6d94c4913732801406a575cdaf3";

    /**
     * 登陆
     *
     * @return
     */
    @PostMapping("/token")
    public Result<?> login(HttpServletRequest request) throws ParseException {

        String token = TokenUtils.getTokenByRequest(request);
        //token是否为空
        if (StringUtils.isBlank(token)) {
            //对历史数据的处理 ：手机+验证码 默认为null，这里调整为 LOGIN_TYPE_SMSCODE
            return Result.error("未获取到登录token，请联系管理员！");
        }
        //String token = ServletUtil.getHeader(request, CommonConstant.TOKEN, Charsets.UTF_8);
        SysUser sysUser = new SysUser();
        redisTemplate.hasKey(CommonConstant.PREFIX_USER_TOKEN + token);
        //SysUser sysUser2 =(SysUser) redisTemplate.opsForValue().get(CommonConstant.PREFIX_USER_TOKEN + token);
        //重新进行登陆
        if (!redisTemplate.hasKey(CommonConstant.PREFIX_USER_TOKEN + token)) {
            log.info("level1 获得的token为：{}", token);
            // LoginVO vo = new LoginVO();
            // SysUser member = new SysUser();

            RedisTemplate redisTemplate = SpringContextUtils.getBean("redisTemplate", RedisTemplate.class);

            //String sign = JwtUtil.sign(member.getUsername(), member.getPassword(), Dict.create().set("platform", "0"));
            Map<String, String> map = new HashMap<String, String>();
            //map.put("token", "u_token:4b8fc7ab945846ff982b8047e2e37893");
            map.put("token", token);
            map.put("app_id", app_id);
            map.put("timestamp", String.valueOf(new Date().getTime() / 1000));
            //map.put("timestamp", "1682354262");
            String access = formatUrlParam(map, "utf-8");
            access = access + appSecret;
            // 基于spring框架中的DigestUtils工具类进行密码加密
            String hashedPwd1 = DigestUtils.md5DigestAsHex((access).getBytes());

            String url = "https://swuser.dingxinwen.com/service/user/getInfo";
            url = url + "?" + "token=" + map.get("token").toString() + "&app_id=" + map.get("app_id").toString() + "&timestamp=" + map.get("timestamp").toString() + "&sign=" + hashedPwd1;
            HttpPost post = new HttpPost(url);
            //拼装json格式请求参数
            JSONObject jsonDdUser = new JSONObject();
            StringEntity entity = new StringEntity("", "UTF-8");
            //设置content编码及类型
            entity.setContentEncoding("UTF-8");
            entity.setContentType("application/json");
            post.setEntity(entity);
            //模拟http post请求发送信息
            HttpClient client = HttpClients.createDefault();
            HttpResponse response;
            JSONObject jsonDdUser2 = new JSONObject();
            try {
                response = (HttpResponse) client.execute(post);
                if (response.getStatusLine().getStatusCode() == 200) {
                    HttpEntity entity_r = response.getEntity();
                    String personal = EntityUtils.toString(entity_r);
                    jsonDdUser = JSON.parseObject(personal);
                    if ("0".equals(jsonDdUser.get("code").toString()))
                        jsonDdUser = JSON.parseObject(JSON.parseObject(personal).get("data").toString());
                    else
                        return Result.error("未获取到登录信息，请联系管理员！");
                }
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                return Result.error("系统异常，请联系管理员！");
            }
            //判断用户信息是否存在，不存在保存用户信息，存在使用

            Result<JSONObject> result = new Result<JSONObject>();
            String phone = jsonDdUser.getString("phone");//手机号
            //Object code = redisUtil.get(phone);
            String username = jsonDdUser.getString("nickname");//用户名
            //未设置用户名，则用手机号作为用户名
            if (oConvertUtils.isEmpty(username)) {
                username = phone;
            }

            //判断库中是否已注册
            sysUser = sysUserService.getUserByPhone(phone);
            //转换生日为时间
            DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
            log.info("jsonDdUser {}", jsonDdUser);
            //如果库中存在信息，更新数据
            if (sysUser != null) {
//                sysUser.setUsername(jsonDdUser.getString("nickname").toString());
//                sysUser.setBirthday(df.parse(jsonDdUser.getString("birthday").toString()));
//                sysUser.setSex("1".equals(jsonDdUser.getString("sex").toString()) ? true : false);
//                sysUser.setAvatar(jsonDdUser.getString("avatar").toString());
//                sysUserService.updateById(sysUser);
                sysUser.setThirdType(cn.com.hhrcw.utils.Constant.LOGIN_TYPE_DDXW_LOGIN);
                sysUser.setUpdateTime(DateUtil.date());
                sysUserService.updateById(sysUser);
            }
            //新增数据
            else {
                sysUser = new SysUser();
                //加密盐
                String salt = oConvertUtils.randomGen(8);
                //未设置密码，则随机生成一个密码
                String passwordEncode = PasswordUtil.encrypt(phone, salt, salt);
                sysUser.setPhone(jsonDdUser.getString("phone"));
//                sysUser.setBirthday(df.parse(jsonDdUser.getString("birthday")));
//                sysUser.setSex("1".equals(jsonDdUser.getString("sex")) ? true : false);
//                sysUser.setAvatar(jsonDdUser.getString("avatar"));
//                sysUser.setUsername(jsonDdUser.getString("nickname"));
                sysUser.setPassword(passwordEncode);
                sysUser.setCreateBy(sysUser.getId());
                sysUser.setCreateTime(DateUtil.date());
                sysUser.setDelFlag(false);
                sysUser.setSalt(salt);
                sysUser.setStatus(1);
                sysUser.setThirdId(appSecret);
                sysUser.setThirdType(cn.com.hhrcw.utils.Constant.LOGIN_TYPE_DDXW_LOGIN);
                sysUser.setCreateTime(DateUtil.date());
                sysUser.setCreateBy("");//创建人
                //sysUser.setUserIdentity("3");
                sysUserService.save(sysUser);
            }
            //失效时间
            final long time = StrUtil.equals(profiles, "dev") ? (Constant.TIME_MIN * 2) : Constant.TIME_MIN;
            // 添加
            redisTemplate.opsForValue().set(CommonConstant.PREFIX_USER_TOKEN + token, sysUser, time, TimeUnit.MINUTES);
            // 金法添加签名 为了个人端可以上传
            redisTemplate.opsForValue().set(CommonConstant.PREFIX_USER_PERSONAL_TOKEN + token, token, time, TimeUnit.MINUTES);

        } else {
            //获取用户信息
            //sysUser = (SysUser) SubjectUtils.getSubject();
            sysUser = (SysUser) redisTemplate.opsForValue().get(CommonConstant.PREFIX_USER_TOKEN + token);
            //测试测试环境数据使用
           // redisTemplate.delete(CommonConstant.PREFIX_USER_TOKEN + token);
           // redisTemplate.delete(CommonConstant.PREFIX_USER_PERSONAL_TOKEN + token);
        }
        //查询简历信息
        JSONObject jsonObject = null;
        if (sysUser != null) {
            jsonObject = (JSONObject) JSONObject.toJSON(sysUser);
            //List<CvResume> cvResumes = resumeService.lambdaQuery().eq(CvResume::getUserId, sysUser.getId()).eq(CvResume::getDelFlag, false).orderByDesc(CvResume::getDelFlag).list();
            List<NewResume> newResumes = newResumeService.lambdaQuery().eq(NewResume::getUserId, sysUser.getId()).eq(NewResume::getDelFlag, false).orderByDesc(NewResume::getCreateTime).list();
          if(newResumes.size() == 0) {
                jsonObject.put("resumeId", "");
            } else {
                jsonObject.put("resumeId", (String) newResumes.get(0).getId());

            }
        }
        return Result.ok(jsonObject);


    }
    /**
     * 数据搜索
     * <pre>
     *      分词搜索: [字段].keywords=网裕测试
     *      精确匹配: [字段].term=民营
     *      大于等于: [字段].gte=1
     *      小于等于: [字段].lte=1
     *      模糊匹配: [字段].like=工程师*    工程师*: 前缀匹配,  *工程师: 后缀匹配
     *      范围搜索: [字段].range=2000,3000
     *      分词搜索多字段匹配: [字段1].keywords,[字段2].keywords=网裕测试
     * <pre/>
     * @return
     */
    @GetMapping("/list")
    @AutoLog
    public Result<?> so(@NotBlank(message = "数据分类必填") String type, BaseParams params, HttpServletRequest request) {
        //SysUser user = (SysUser) SubjectUtils.getSubject();
        Map<String, String[]> map = request.getParameterMap();

        boolean experienceRange = map.containsKey("experience.range");
        if (experienceRange) {
            String[] strings = map.get("experience.range");
            map.put("minExperience.gte", new String[]{strings[0].split(",")[0]});
            map.put("maxExperience.lte", new String[]{strings[0].split(",")[1]});
            map.remove("experience.range");
        }
        String[] strings = null;
        boolean moneyRange = map.containsKey("money.range");
        if (moneyRange) {
            strings = map.get("money.range");
            map.remove("money.range");
        }
        //招聘类型转换  type: number, //0-全部 (默认) --》空;//1-校园招聘 --1;//2-社会招聘  --0
        if(StringUtils.isNotBlank(type)){
            switch (type) {
                case "1":
                    map.put("recruitType.keywords",new String[]{"1"});
                    break;
                case "2":
                    map.put("recruitType.keywords",new String[]{"0"});
                    break;
                case "0":
                    break;
                default:
                    return Result.error("招聘类型错误！");
            }
//            if("1".equals(type))
//                map.put("recruitType.keywords",new String[]{"1"});
//            else if("2".equals(type))
//                map.put("recruitType.keywords",new String[]{"0"});
//            else if("1".equals(type))
//                return Result.error("收藏失败");
        }

        if((!"null".equals(String.valueOf(map.get("companyId"))))&&StringUtils.isNotBlank(String.valueOf(map.get("companyId")))) {
            map.put("companyId.term", map.remove("companyId"));
        }
        if((!"null".equals(String.valueOf(map.get("title"))))&&StringUtils.isNotBlank(String.valueOf(map.get("title")))){
            map.put("title.keywords,companyName.keywords", map.remove("title"));
        }
        map.put("channel.term",new String[]{cn.com.hhrcw.utils.Constant.LOGIN_TYPE_DDXW_LOGIN});
        //上市公司、事业单位、医院、合资、国企、学校/下级学院、股份制企业
        //map.put("enNature.in",new String[]{"上市公司","事业单位","医院","合资","国企","学校/下级学院","股份制企业"});
//        map.put("enNature.in",new String[]{"上市公司,事业单位,医院,合资,国企,学校/下级学院,股份制企业"});
        Object val = null;
        SearchRequest searchRequest = elasticsearchService.build(map);
        if (ArrayUtil.isNotEmpty(strings)) {
            strings = strings[0].split(",");
            BoolQueryBuilder builder = (BoolQueryBuilder) searchRequest.source().query();
            BoolQueryBuilder should = QueryBuilders.boolQuery();
            should.should(QueryBuilders.rangeQuery("minMoney").lte(strings[1]).gte(strings[0]));
            should.should(QueryBuilders.rangeQuery("maxMoney").lte(strings[1]).gte(strings[0]));
            builder.must(should);
        }
        //智能匹配
        List<SortBuilder<?>> sorts = searchRequest.source().sorts();
        if (sorts == null) {
            searchRequest.source().sort(SortBuilders.scoreSort());
        } else {
            sorts.add(0, SortBuilders.scoreSort());
        }
        searchRequest.source().sort("refreshNo", SortOrder.DESC).sort("publishTime", SortOrder.DESC);
        val = elasticsearchService.searchForPage(searchRequest, params.page(), JobPositionDocument.class);
        //h5
//        Object val = null;
//                searchRequest = elasticsearchService.build(map);
//                searchRequest.source().sort("publishTime", SortOrder.DESC);
//                val = elasticsearchService.searchForPage(searchRequest, params.page(), JobPositionDocument.class);
        return Result.ok(val);
    }
    /**
     * 收藏职位
     *
     * @String jobId 请求参数
     * @return
     */
    @GetMapping(value = "/add")
    @AutoLog("职位=收藏职位-添加")
    @ApiOperation(value = "添加", notes = "添加")
    public Result<?> add(@NotBlank(message = "jobId必填") String jobId, String type) {
        SysUser sysUser = (SysUser) SubjectUtils.getSubject();
        try {
            OpJob opJob = jobService.getById(jobId);
            if (null == opJob || opJob.getDelFlag().equals(true)) {
                return Result.error("未查询到职位信息");
            }
            LambdaUpdateWrapper<OpCollection> queryWrapper =  Wrappers.lambdaUpdate();
            queryWrapper.eq(OpCollection::getDelFlag, false);//删除标识

            queryWrapper.eq(OpCollection::getUserId, sysUser.getId());
            queryWrapper.eq(OpCollection::getJobId, jobId);
            List<OpCollection> list = opCollectionService.list(queryWrapper);//理论上只纯在一条有效
            //判断是否传输错误等，已收藏后type=0，继续收藏
            if (CollectionUtils.isNotEmpty(list)&&"0".equals(type)){
                return Result.error("该职位已收藏");
            }
            //取消收藏
            else if (CollectionUtils.isNotEmpty(list)&&"1".equals(type)){
                list.get(0).setDelFlag(true);//取消收藏，删除
                opCollectionService.updateById(list.get(0));
                //opCollectionService.update(list.get(0));
            }
            //新增收藏
            else if (CollectionUtils.isEmpty(list)&&"0".equals(type)) {
                OpCollection opCollection = new OpCollection();//opCollectionConvert.toEntity();
                opCollection.setCreateBy(sysUser.getId());
                opCollection.setJobId(jobId);
                opCollection.setCreateTime(DateUtil.date());
                opCollection.setDelFlag(false);
                opCollection.setUserId(sysUser.getId());
                opCollection.setTime(DateUtil.date());
                opCollection.setChannel(cn.com.hhrcw.utils.Constant.LOGIN_TYPE_DDXW_LOGIN);
                //opCollection.setNo(super.sort("op_collection", Constant.NO_SEED));//FIXME: 编号,可根据情况隐藏
                 opCollectionService.save(opCollection);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
//        finally {
//            redisTemplate.delete(key);
//        }
        return  Result.ok("操作成功") ;
    }
    /**
     * @param encode 编码
     * @return
     */
    public static String formatUrlParam(Map<String, String> param, String encode) {
        String params = "";
        Map<String, String> map = param;

        try {
            List<Map.Entry<String, String>> itmes = new ArrayList<Map.Entry<String, String>>(map.entrySet());

            //对所有传入的参数按照字段名从小到大排序
            //Collections.sort(items); 默认正序
            //可通过实现Comparator接口的compare方法来完成自定义排序
            Collections.sort(itmes, new Comparator<Map.Entry<String, String>>() {
                @Override
                public int compare(Entry<String, String> o1, Entry<String, String> o2) {
                    // TODO Auto-generated method stub
                    return (o1.getKey().toString().compareTo(o2.getKey()));
                }
            });

            //构造URL 键值对的形式
            StringBuffer sb = new StringBuffer();
            for (Map.Entry<String, String> item : itmes) {
                if (StringUtils.isNotBlank(item.getKey())) {
                    String key = item.getKey();
                    String val = item.getValue();
                    //val = URLEncoder.encode(val, encode);
                    sb.append(key + "=" + val);
                    //sb.append("&");
                }
            }
            params = new String(sb.toString().getBytes(), "UTf-8");
            ;
//            if (!params.isEmpty()) {
//                params = params.substring(0, params.length() - 1);
//            }
        } catch (Exception e) {
            return "";
        }
        return params;
    }
    /**
     * 文件上传统一方法
     *
     * @param request
     * @param response
     * @return
     */
    @PostMapping(value = "/upload")
    @AutoLog(logType = 2, ty = "upload", value = "上传文件")
    @ApiOperation(value = "文件上传方法", notes = "文件上传方法")
    public Result<?> upload(HttpServletRequest request, HttpServletResponse response) throws IOException {
        SysUser sysUser = (SysUser) SubjectUtils.getSubject();
        LoginUser sysUser2 = (LoginUser) SecurityUtils.getSubject().getPrincipal();

        Result<Object> result = new Result<>();
        String bizPath = request.getParameter("biz");
        String fileType = request.getParameter("fileType");
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        // 获取上传文件对象
        MultipartFile file = multipartRequest.getFile("file");
        List<DictModel> models = sysBaseApi.queryDictItemsByCode("upload_type");
        log.info("{}", file.getBytes().length);
        //后缀校验
        DictModel model = models.stream().filter(elem -> StringUtils.equals("write_list", elem.getText())).findFirst().orElseGet(null);
        String name = file.getOriginalFilename();
        if (BrowserUtils.isIe(request)) {
            name = FileUtil.getName(name);
        }
        String ext = name.substring(name.lastIndexOf(".") + 1);
        if (model != null) {
            String[] exts = model.getValue().split(",");
            if (!ArrayUtils.contains(exts, ext)) {
                return Result.error("文件不合法");
            }
        }
        if (oConvertUtils.isEmpty(bizPath)) {
            if (org.jeecg.common.constant.CommonConstant.UPLOAD_TYPE_OSS.equals(uploadType)) {
                //未指定目录，则用阿里云默认目录 upload
                bizPath = "upload";
            } else {
                bizPath = "";
            }
        }
        if (org.jeecg.common.constant.CommonConstant.UPLOAD_TYPE_LOCAL.equals(uploadType)) {
            //针对jeditor编辑器如何使 lcaol模式，采用 base64格式存储
            String jeditor = request.getParameter("jeditor");
            if (oConvertUtils.isNotEmpty(jeditor)) {
                result.setMessage(org.jeecg.common.constant.CommonConstant.UPLOAD_TYPE_LOCAL);
                result.setSuccess(true);
                return result;
            } else {
                //Object obj = sysBaseApi.uploadToLocal(file.getBytes(), bizPath, name, Convert.toInt(fileType), true);
                Object obj = topJobClientService.uploadToLocal(file.getBytes(), bizPath, name, Convert.toInt(fileType), true);
                result.setSuccess(true);
                result.setResult(obj);
            }
        }
        return result;
    }
}
